import 'dart:async';
import 'dart:convert';

import 'package:flutter/foundation.dart';
import 'package:flutter_deer/database/tables.dart';
import 'package:flutter_deer/util/socket/BaseMdcControl.dart';
import 'package:flutter_deer/util/socket/bean/fcc_cmd.dart';
import 'package:flutter_deer/util/socket/socket_client_manager.dart';
import 'package:injectable/injectable.dart';
import 'package:rxdart/rxdart.dart';

@singleton
class MdcDefaultControlImpl extends BaseMdcControl {
  static const String _mdcTag = '[mdc_tag_jy] ';
  final SocketClientManager _socketClientManager = SocketClientManager();
  final _chlMap = <int, List<int>>{};
  final _subscriptions = CompositeSubscription();

  @override
  void initAndStart(String pzIPv4, int uPort) {
    _socketClientManager.addClient(pzIPv4, uPort);
    // 只执行一次
    startLoop();
  }

  final state = AppOrderBean();
  // 解析数据，处理
  void parseData(int mdcNo, dynamic data) {
    // 提取 cmdType
    final cmdType = data['cmdType'] as int;
    // 根据 cmdType 执行相应的操作
    switch (cmdType) {
      case FccCMD.TPumpState:
        state.mdcNo = mdcNo;
        AppOrderBean.fromJsonState(state, data);
        stateStreamController.add(state);
        // print('$_mdcTag---> [TPumpState]');
      case FccCMD.TPumpOrder:
        final AppOrderBean order = AppOrderBean.fromJsonOrder(data)..mdcNo = mdcNo;
        orderStreamController.add(order);
        // print('$_mdcTag---> [order]');

        //1、接收订单，如果不是回叫订单，检查时间
        final List<MdcCallBackBean> queryList = MdcCallBackBean.queryCallBackBean(order);
        if (queryList.isEmpty) {
          final int timeGap = order.mdcOrderTime - DateTime.now().millisecondsSinceEpoch;
          // print('$_mdcTag---> [timeGap] $timeGap');
        }
        //2、补齐通道号
        addChannel(order.mdcNo, order.chl);
        //3、删除回叫任务
        MdcCallBackBean.deleteCallBackBean(order);
        //4、去重入库
        AppOrderBean.insertOrder(order);
        //5、入库回应 todo

        //6、更新最大TTC 和 添加回叫任务
        MdcMaxTtcBean.checkAndAddCallBack(order);
        //7、执行回叫任务
        _executeCallBackTask(order.mdcNo, order.chl);
        break;
      case FccCMD.GetMaxTTC:
        final MdcMaxTtcBean tMaxTtcBean = MdcMaxTtcBean.fromJson(data)..mdcNo = mdcNo;
        //2、补齐通道号
        addChannel(mdcNo, tMaxTtcBean.chl);
        // print('$_mdcTag---> [TMaxTtc]');
        // 更新本地maxTTC记录 和 添加回叫任务
        MdcMaxTtcBean.checkAndAddCallBackByMax(mdcNo, tMaxTtcBean.chl, tMaxTtcBean.maxTTC);
        break;
    }
  }

  // 执行回叫任务
  void _executeCallBackTask(int mdcNo, int chlNo) {
    final List<MdcCallBackBean> queryList = MdcCallBackBean.queryCallBackBeanByChl(mdcNo, chlNo);
    // 只取第一条数据
    final MdcCallBackBean bean = queryList.first;
    // 查询_socketClientManager.clients.values中mdcNo和chlNo相同的client
    for (final client in _socketClientManager.clients.values) {
      if (client.getIndexMdc() == mdcNo) {
        client.sendData(
          (MdcCallBackBean()
                ..fccTTC = bean.fccTTC
                ..chl = bean.chl)
              .toServerJsonMap(),
        );
        break;
      }
    }
    // client.executeCallBackTask(bean);
    // 打印日志
    // print('Execute call back task executed');
  }

  // 查询最大ttc的任务
  void _queryMaxTtcTask() {
    final clients = _socketClientManager.clients.values.toList();
    for (int index = 0; index < clients.length; index++) {
      final client = clients[index];
      final channels = _chlMap.putIfAbsent(client.getIndexMdc(), () => <int>[]);
      if (channels.isEmpty) {
        for (int i = 1; i <= 16; i++) {
          client.sendData(
            (MdcMaxTtcBean()..chl = i).toServerJsonMap(),
          );
        }
      } else {
        for (final value in channels) {
          client.sendData(
            (MdcMaxTtcBean()..chl = value).toServerJsonMap(),
          );
        }
      }
    }
    // 打印日志
    // print('Query max ttc task executed');
    _updateHubTimeTask();
  }

  // 更新集线器时间的任务
  void _updateHubTimeTask() {
    // 执行更新集线器时间的操作
    // client.updateHubTime();
    // 打印日志
    // print('Update hub time task executed');
  }

  // 用于标记循环是否正在运行
  bool _isLoopRunning = false;

  // 用于存储循环的定时器
  Timer? _loopTimer;

  // 用于启动循环
  void startLoop() {
    if (_isLoopRunning) {
      return;
    }

    _isLoopRunning = true;
    _loopTimer = Timer.periodic(const Duration(seconds: kDebugMode ? 2000 : 60), (timer) {
      // 执行循环任务
      _queryMaxTtcTask();
      // 清空循环任务
    });

    // 监听连接状态
    _subscriptions.add(_socketClientManager.connectionStateStream.listen((message) {
      mdcStateStreamController.add(message);
      // print('$_mdcTag---> server_connect: $message');
    }));

    // 监听数据接收
    _subscriptions.add(_socketClientManager.dataStream.listen((intStr) {
      try {
        final data = jsonDecode(intStr.value);
        parseData(intStr.key, data);
      } catch (e) {
        // print('$_mdcTag---> form server: $e');
      }
    }));
  }

  // 用于停止循环
  void stopLoop() {
    if (!_isLoopRunning) {
      return;
    }
    _isLoopRunning = false;
    _loopTimer?.cancel();
    _loopTimer = null;
  }

  void addChannel(int mdcNo, int chlNo) {
    final channels = _chlMap.putIfAbsent(mdcNo, () => <int>[]);
    if (!channels.contains(chlNo)) {
      channels.add(chlNo);
    }
  }

  @override
  void clickCallBackNzlAll() {}

  @override
  void delThisMdc(String pzIPv4, int uPort) {
    _socketClientManager.disconnectClient(pzIPv4, uPort);
  }

  @override
  void getAllPumpCode() {}

  @override
  void queryTTC(int chlNo) {}

  @override
  void refreshMachineTime() {}

  @override
  void setGunPriceByGunNo(List<MdcSetPrcNzlCmdBeanPrcOil> list) {

  }

  @override
  void dispose() {
    super.dispose();
    stopLoop();
    _subscriptions.dispose();
  }
}
